/**
 * User: alesj
 * Date: 2005.3.25
 * Time: 16:06:52
 * 
 * (C) Genera Lynx d.o.o.
 */

package com.generalynx.ecos.web.form;

import com.generalynx.ecos.page.Page;
import com.generalynx.ecos.web.object.PageCommand;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.RequestUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class PageForm extends AbstractForm {

    private String hql;
    private DetachedCriteria criteria;
    private int pageSize = Page.DEFAULT_SIZE;

    protected void initApplicationContext() {
        super.initApplicationContext();
        if (getHql() == null && getCriteria() == null) {
            throw new IllegalArgumentException("HQL and Criteria both cannot be null!");
        }
        if (getCommandClass() == null) {
            setCommandClass(PageCommand.class);
        } else if (!PageCommand.class.isAssignableFrom(getCommandClass())) {
            throw new IllegalArgumentException("Command class must extend PageCommand!");
        }
    }

    private int getPageNumber(HttpServletRequest request) {
        int page = RequestUtils.getIntParameter(request, "page", 0);
        if (page > 0) {
            return page;
        }
        Number pageNumber = (Number)request.getAttribute("pageNumber");
        return (pageNumber != null ? pageNumber.intValue() : 0);
    }

    protected Page createPage(int pageNumber) {
        Page page;
        if (getHql() != null) {
            page = getBasicDAO().loadPage(getHql(), pageNumber, getPageSize());
        } else {
            page = getBasicDAO().loadPage(getCriteria(), pageNumber, getPageSize());
        }
        return page;
    }

    /* override */
    protected Page createPage(HttpServletRequest request) {
        return createPage(getPageNumber(request));   
    }

    protected ModelAndView showForm(HttpServletRequest request,
                                    HttpServletResponse response,
                                    BindException errors) throws Exception {
        request.setAttribute("page", createPage(request));
        return super.showForm(request, response, errors);
    }

    /* override */
    protected ModelAndView internalOnSubmit(HttpServletRequest request,
                                          HttpServletResponse response,
                                          PageCommand pageCommand, BindException errors) throws Exception {
        return showForm(request, response, errors);
    }

    protected ModelAndView onSubmit(HttpServletRequest request,
                                    HttpServletResponse response,
                                    Object command,
                                    BindException errors) throws Exception {
        PageCommand pageCommand = (PageCommand)command;
        if (pageCommand.isPageAction()) {
            request.setAttribute("pageNumber", new Integer(pageCommand.getPage()));
            return showForm(request, response, errors);
        } else {
            return internalOnSubmit(request, response, pageCommand, errors);
        }
    }

    //--------------------------------------------------------

    public String getHql() {
        return hql;
    }

    public void setHql(String hql) {
        this.hql = hql;
    }

    public DetachedCriteria getCriteria() {
        return criteria;
    }

    public void setCriteria(DetachedCriteria criteria) {
        this.criteria = criteria;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

}
